﻿using KinonekoSoftware.CodariaDB.Documents.Composes;
using KinonekoSoftware.Foundation.IO;
using LiteDB;
using QuikGraph;

namespace KinonekoSoftware.Studio.Pages.Notions
{
    public sealed class SampleNotion : RootObject, INotion
    {
        private string _name;
        private string _intro;
        
        public  string ParentID { get; set; }
        
        /// <summary>
        /// 获取或设置 <see cref="Intro"/> 属性。
        /// </summary>
        public string Intro
        {
            get => _intro;
            set => SetValue(ref _intro, value);
        }

        /// <summary>
        /// 获取或设置 <see cref="Name"/> 属性。
        /// </summary>
        public string Name
        {
            get => _name;
            set => SetValue(ref _name, value);
        }
    }
    
    
    public sealed class SampleNotionEdge : RootObject, IEdge<SampleNotion>
    {
        private string _name;

        /// <summary>
        /// 获取或设置 <see cref="Name"/> 属性。
        /// </summary>
        public string Name
        {
            get => _name;
            set => SetValue(ref _name, value);
        }
        
        public SampleNotion Source { get; init; }
        public SampleNotion Target { get; init; }
    }
    
    
    public sealed class InspirationGalleryViewModel : RepositoryGalleryItem
    {
        private readonly ObservableStack<SampleNotion>                      _notionStack;
        private readonly List<SampleNotion>                                 _notionCollection;
        private readonly BidirectionalGraph<SampleNotion, SampleNotionEdge> _notionGraph;
        private readonly LiteDatabase                                       _database;
        private readonly ILiteCollection<SampleNotion>                      _collection;

        private SampleNotion _focusingNotion;

        public InspirationGalleryViewModel()
        {
            var dir      = FolderHelper.CheckDir(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleDatas"));
            var fileName = Path.Combine(dir, "notion.projDB");
            _notionStack      = new ObservableStack<SampleNotion>();
            _notionCollection = new List<SampleNotion>(32);
            _notionGraph      = new BidirectionalGraph<SampleNotion, SampleNotionEdge>();
            Notions           = new ObservableCollection<SampleNotion>();
            _database         = new LiteDatabase(fileName);
            _collection       = _database.GetCollection<SampleNotion>("notion");

            AddNotionCommand      = CreateCommand(DoAddNotionCommand);
            DeepDiveNotionCommand = CreateCommand<SampleNotion>(DoDeepDiveNotionCommand);
            RemoveNotionCommand   = CreateCommand<SampleNotion>(DoRemoveNotionCommand);
        }

        protected override void ReleaseUnmanagedResources()
        {
            _database.Dispose();
        }

        private async void DoAddNotionCommand()
        {
            var r = await SingleText("新建灵感", "用简短的语言描述这个灵感", null, 50);

            if (!r.IsFinished)
            {
                return;
            }

            //
            // 默认的灵感实现为: StoryPoint
            var notion = new SampleNotion
            {
                Id   = ID.Get(),
                Name = r.Value,

            };

            if (_notionStack.Count > 0)
            {
                notion.ParentID = _notionStack.Peek().Id;
            }
            
            //
            // 添加到集合当中。
            _notionGraph.AddVertex(notion);
            _notionCollection.Add(notion);
            _collection.Insert(notion);
            Notions.Add(notion);
            RaiseUpdated(nameof(IsFocusingNotionEmpty));
        }

        private void DoDeepDiveNotionCommand(SampleNotion target)
        {
            if (target is null)
            {
                return;
            }
            
            //
            //
            _notionStack.Push(FocusingNotion);
            Notions.Clear();
            RaiseUpdated(nameof(IsFocusingNotionEmpty));
        } 
        
        private async void DoRemoveNotionCommand(SampleNotion target)
        {
            if (target is null)
            {
                return;
            }
            
            //
            //
            _notionStack.Push(FocusingNotion);
            Notions.Remove(target);
            RaiseUpdated(nameof(IsFocusingNotionEmpty));
        }
        
        public ICommandEX AddNotionCommand       { get; }
        public ICommandEX DeepDiveNotionCommand { get; }
        public ICommandEX EditNotionCommand      { get; }
        public ICommandEX RemoveNotionCommand    { get; }

        public ObservableStack<SampleNotion> NotionLayer => _notionStack;
        

        public bool IsFocusingNotionEmpty => Notions.Count > 0;

        public SampleNotion FocusingNotion
        {
            get => _focusingNotion;
            set => SetValue(ref _focusingNotion, value);
        }

        public ObservableCollection<SampleNotion>                 Notions { get; }
        public BidirectionalGraph<SampleNotion, SampleNotionEdge> Graph   => _notionGraph;
    }
}